#include "em-vm.h"
#include "syscall.h"
#include <stdio.h>

uint8_t bytecode0[] = {
        0x0, 0x0, 0x0, 0x10,  // head
        0x16, 0x0, 0x0, 0x0,
        0x20, 0x0, 0x0, 0x0,

        // .data
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,

        // .rodata
        'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', ' ', '!', '\n', '\0', ' ',

        // .text
        0x80, 0x0, 0x10, 0x0, 0x0, 0x0, // PTR_STORE 0x0 .rodata
        0x1, 0x1, 0x0, 0x0, 0x0, 0x0,   // INT_STORE 0x1 0

        0x52, 0x2,                      // PRE_SYSCALL 0x2

        0x1, 0x4, 0x4, 0x0, 0x0, 0x0,   // INT_STORE 0x4 4

        0x81, 0x3, 0x0, 0x1,            // PTR_TO_INT 0x3 0x0 0x1
        0x29, 0x1, 0x4, 0x0,            // INC 0x1 4
        0x70, 0x3,                      // STACK_PUSH 0x3

        0x2a, 0x4, 0x1, 0x0,            // DEC 0x4 1
        0x12, 0x34, 0x0, 0x0, 0x0,      // JUMP_NZ 0x34

        0x53, 0x2, 0x2, 0x0,            // SYSCALL 0x2 2

        0x0,                  // EXIT
};

uint8_t bytecode1[] = {
        0x0, 0x0, 0x0, 0x10,  // head
        0x0, 0x0, 0x0, 0x0,
        0xf, 0x0, 0x0, 0x0,

        // .data

        // .rodata
        'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', ' ', '!', '\n', '\0',

        // .text
        0x80, 0x0, 0x0, 0x0, 0x0, 0x0,  // PTR_STORE 0x0 .rodata
        0x52, 0x1,                      // PRE_SYSCALL 0x2
        0x71, 0x0,                      // STACK_PUSH_PTR 0x0
        0x53, 0x1, 0x3, 0x0,            // SYSCALL 0x2 3
        0x0,                            // EXIT
};

uint8_t bytecode2[] = {
        0x0, 0x0, 0x0, 0x10,  // head
        0x0, 0x0, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0,

        // .data
        // .rodata
        // .text
        0x52, 0x1,                      // PRE_SYSCALL 0x1
        0x30, 0x0, 0xe, 0x0, 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', ' ', '!', '\n',
        0x72, 0x0,                      // STACK_PUSH_STR 0x0
        0x30, 0x0, 0x7, 0x0, 'q', 'w', 'e', 'r', 't', 'y', '\n',
        0x72, 0x0,                      // STACK_PUSH_STR 0x0
        0x53, 0x1, 0x2, 0x0,            // SYSCALL 0x1 2
        0x0,                            // EXIT
};

uint8_t bytecode3[] = {
        0x0, 0x0, 0x0, 0x10,  // head
        0x0, 0x0, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0,

        0x1, 0x1, 0xe, 0x0, 0x0, 0x0,
        0x75, 0x22, 0x0, 0x0, 0x0,

        0x1, 0x1, 0xfe, 0x0, 0x0, 0x0,
        0x75, 0x22, 0x0, 0x0, 0x0,

        0x1, 0x1, 0xff, 0x0, 0xff, 0x0,
        0x75, 0x22, 0x0, 0x0, 0x0,

        0x0,

        0x52, 0x0,
        0x70, 0x1,
        0x53, 0x0, 0x4, 0x0,

        0x52, 0x0,
        0x30, 0x1, 0x1, 0x0, '\n',
        0x72, 0x1,
        0x53, 0x0, 0x2, 0x0,
        0x74,
};

int alloc_cnt;

int main()
{
    em_vm_t *vm = create_vm(bytecode1, syscall);

    if (vm != NULL)
    {
        vm_exec(vm);

        vm_restart(vm);
        vm_exec(vm);

        vm_restart(vm);
        vm_exec(vm);

        vm_restart(vm);
        vm_exec(vm);
    }
    vm_destroy(vm);

    printf("\nalloc : %d\n", alloc_cnt);

    return 0;
}
